package com.fand.configuration.dao;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.joda.time.DateTime;

import com.fand.configuration.dto.DictionaryDeDto;
import com.fand.configuration.dto.DictionaryDto;
import com.fand.configuration.dto.DictionaryTyDto;
import com.fand.dto.PaginationDto;
import com.fand.persistent.builder.ModelArgs;
import com.fand.persistent.builder.ModelBuilder;
import com.fand.persistent.builder.ModelBuilderUtils;
import com.fand.persistent.support.JdbcDaoSupport;
import com.google.common.collect.Maps;

/**
 * 字典
 * 
 * @author yaoHT
 */
public class JdbcDictionaryDao extends JdbcDaoSupport implements DictionaryDao {
	@Override
	public int deleteDictionaryDeBy1(final String entityId) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, "entityId", null,
		        entityId);
		
		return this.update("configuration/dictionaryDe/deleteDictionaryDeBy1", modelBuilder.build());
	}
	
	@Override
	public int deleteDictionaryTyByIds(final String ids) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("IDS", ids);
		
		return this.update("configuration/dictionaryTy/deleteDictionaryTyBy101", model);
	}
	
	@Override
	public PaginationDto<Map<String, Object>> paginationDictionaryTyBy1ForMapList(
	        final DictionaryTyDto dictionaryTy) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("CODE", dictionaryTy.getCode());
		
		model.put("VALUE", dictionaryTy.getValue());
		
		model.put("DICTIONARY_CODE", dictionaryTy.getDictionaryCo());
		
		return this.paginationForMapList("configuration/dictionaryTy/selectDictionaryTyBy101ForObject",
		        "configuration/dictionaryTy/selectDictionaryTyBy101ForMappedObjectList",
		        dictionaryTy.getPaginationNo(), dictionaryTy.getPaginationSize(), model);
	}
	
	@Override
	public String saveDictionaryBy1ForObject(final DictionaryDto dictionary) {
		final ModelBuilder selectModelBuilder = ModelBuilderUtils.newModelBuilder()
		        .putExtend(null, "code", null, dictionary.getCode())
		        .putExtend(null, "typeId", null, dictionary.getTypeId());
		
		final DictionaryDto oldDictionary = this.selectForMappedObject(DictionaryDto.class,
		        "configuration/dictionary/selectDictionaryBy1ForMappedObjectList", selectModelBuilder.build());
		
		if (oldDictionary == null) {
			final Date deginDaTi = new Date();
			final DateTime endDaTi = new DateTime(9999, 12, 31, 0, 0, 0, 0);
			
			dictionary.setBeginDaTi(deginDaTi);
			dictionary.setEndDaTi(endDaTi.toDate());
			dictionary.setId(UUID.randomUUID().toString());
			
			final ModelBuilder insertModelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(
			        ModelBuilder.INSERT, dictionary));
			
			this.update("configuration/dictionary/insertDictionaryBy1", insertModelBuilder.build());
			
			return dictionary.getId();
		}
		
		do {
			if (!StringUtils.equals(oldDictionary.getTypeId(), dictionary.getTypeId())) {
				break;
			}
			
			if (!StringUtils.equals(oldDictionary.getName(), dictionary.getName())) {
				break;
			}
			
			if (NumberUtils.compare(oldDictionary.getOrderNum(), dictionary.getOrderNum()) != 0) {
				break;
			}
			
			return oldDictionary.getId();
		} while (false);
		
		final ModelBuilder updateModelBuilder = ModelBuilderUtils.newModelBuilder(
		        new ModelArgs(ModelBuilder.UPDATE, dictionary, "orderNum", "name")).putExtend(null, "id", null,
		        oldDictionary.getId());
		
		this.update("configuration/dictionary/updateDictionaryBy1", updateModelBuilder.build());
		
		return oldDictionary.getId();
	}
	
	@Override
	public int saveDictionaryDeBy1ForObject(final DictionaryDeDto dictionaryDe) {
		final ModelBuilder modelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, "entityId", null,
		        dictionaryDe.getEntityId());
		
		final int count = this.selectForObject(Integer.class,
		        "configuration/dictionaryDe/selectDictionaryDeBy1ForObject", null, modelBuilder.build());
		
		if (count > 0) { return 0; }
		
		final Date deginDaTi = new Date();
		final DateTime endDaTi = new DateTime(9999, 12, 31, 0, 0, 0, 0);
		
		dictionaryDe.setBeginDaTi(deginDaTi);
		dictionaryDe.setEndDaTi(endDaTi.toDate());
		dictionaryDe.setId(UUID.randomUUID().toString());
		
		modelBuilder.putObjectField(new ModelArgs(ModelBuilder.INSERT, dictionaryDe));
		
		return this.update("configuration/dictionaryDe/insertDictionaryDeBy1", modelBuilder.build());
	}
	
	@Override
	public String saveDictionaryTyBy1ForObject(final DictionaryTyDto dictionaryTy) {
		final ModelBuilder selectModelBuilder = ModelBuilderUtils.newModelBuilder().putExtend(null, "code", null,
		        dictionaryTy.getCode());
		
		final DictionaryTyDto oldDictionaryTy = this
		        .selectForMappedObject(DictionaryTyDto.class,
		                "configuration/dictionaryTy/selectDictionaryTyBy1ForMappedObjectList",
		                selectModelBuilder.build());
		
		if (oldDictionaryTy == null) {
			final Date deginDaTi = new Date();
			final DateTime endDaTi = new DateTime(9999, 12, 31, 0, 0, 0, 0);
			
			dictionaryTy.setBeginDaTi(deginDaTi);
			dictionaryTy.setEndDaTi(endDaTi.toDate());
			dictionaryTy.setId(UUID.randomUUID().toString());
			
			final ModelBuilder insertModelBuilder = ModelBuilderUtils.newModelBuilder(new ModelArgs(
			        ModelBuilder.INSERT, dictionaryTy));
			
			this.update("configuration/dictionaryTy/insertDictionaryTyBy1", insertModelBuilder.build());
			
			return dictionaryTy.getId();
		}
		
		do {
			if (!StringUtils.equals(oldDictionaryTy.getName(), dictionaryTy.getName())) {
				break;
			}
			
			if (!StringUtils.equals(oldDictionaryTy.getParentId(), dictionaryTy.getParentId())) {
				break;
			}
			
			if (NumberUtils.compare(oldDictionaryTy.getOrderNum(), dictionaryTy.getOrderNum()) != 0) {
				break;
			}
			
			return oldDictionaryTy.getId();
		} while (false);
		
		final ModelBuilder updateModelBuilder = ModelBuilderUtils.newModelBuilder(
		        new ModelArgs(ModelBuilder.UPDATE, dictionaryTy, "orderNum", "name", "parentId")).putExtend(null,
		        "id", null, oldDictionaryTy.getId());
		
		this.update("configuration/dictionaryTy/updateDictionaryTyBy1", updateModelBuilder.build());
		
		return oldDictionaryTy.getId();
	}
	
	@Override
	public String selectDictionaryBy1ForObject(final String dictionaryTyCo, final String dictionaryCo) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("dictionaryTyCo", dictionaryTyCo);
		model.put("dictionaryCo", dictionaryCo);
		
		final String id = this.selectForObject(String.class,
		        "configuration/dictionary/selectDictionaryBy2ForObject", "id", model);
		
		return id;
	}
	
	@Override
	public List<DictionaryTyDto> selectDictionaryTyBy201ForMappedObject(final DictionaryTyDto dictionaryTy) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("ID", dictionaryTy.getId());
		model.put("PARENT_ID", dictionaryTy.getParentId());
		
		return this.selectForMappedObjectList(DictionaryTyDto.class,
		        "configuration/dictionaryTy/selectDictionaryTyBy201ForMappedObjectList", model);
	}
	
	@Override
	public int selectDictionaryTyBy201ForObject(final DictionaryTyDto dictionaryTy) {
		final Map<String, Object> model = Maps.newHashMap();
		
		model.put("ID", dictionaryTy.getId());
		model.put("CODE", dictionaryTy.getCode());
		
		return this.selectForObject(Integer.class, "configuration/dictionaryTy/selectDictionaryTyBy201ForObject",
		        null, model);
	}
}